import type { CSSProperties, VNode } from 'vue';
import type { ButtonProps as AntdButtonProps, RowProps } from 'ant-design-vue';
import { NamePath } from 'ant-design-vue/lib/form/interface';
import type { RuleObject, FormProps as AntdFormProps, FormItemProps } from 'ant-design-vue/lib/form';
import type { ColEx, ComponentType } from './formItem';
import type { TableActionType } from '#/Table';

export type Rule = RuleObject & {
	trigger?: 'blur' | 'change' | ['change', 'blur'];
};

export interface RenderCallbackParams {
	schema: FormSchema;
	values: Recordable;
	model: Recordable;
	field: string;
}

export interface ButtonProps extends AntdButtonProps {
	text?: string;
}

export type RegisterFn = (formInstance: FormActionType) => void;

export type FieldMapToTime = [string, [string, string], string?][];

export type UseFormReturnType = [RegisterFn, FormActionType];

export interface FormProps extends AntdFormProps {
	// 统一设置label的宽度
	labelWidth?: string | number;
	// 提交后清空表单
	submitOnReset?: boolean;
	rowProps?: RowProps;
	baseRowStyle?: CSSProperties;
	schemas?: FormSchema[];
	// 全局设置：是否将label加入到错误信息中（当不提供错误信息时自动生成）
	rulesMessageJoinLabel?: boolean;
	disabled?: boolean;
	// compact mode
	compact?: boolean;
	// 在INPUT组件上单击回车时，是否自动提交
	autoSubmitOnEnter?: boolean;
	// 是否聚焦第一个输入框，只在第一个表单项为input的时候作用
	autoFocusFirstItem?: boolean;
	// 自动设置placholder
	autoSetPlaceHolder?: boolean;
	// 是否显示收起展开按钮
	showAdvancedButton?: boolean;
	// 转换日期格式
	transformDateFunc?: (date: Date) => string;

	// 显示重置按钮
	showResetButton?: boolean;
	// 重置按钮配置
	resetButtonOptions?: Partial<ButtonProps>;

	// 显示操作按钮组？
	showActionButtonGroup?: boolean;
	// 显示确认按钮
	showSubmitButton?: boolean;
	// 确认按钮配置
	submitButtonOptions?: Partial<ButtonProps>;

	// 自定义重置函数
	resetFunc?: () => Promise<void>;
	submitFunc?: () => Promise<void>;
	// 是否展示冒号
	colon?: boolean;
	baseColProps?: Partial<ColEx>;
	actionColOptions?: Partial<ColEx>;
	// 针对rangePicker，要将一个时间段拆分为2个时间字段
	fieldMapToTime?: FieldMapToTime;
}

// Form.Item
export interface FormSchema {
	field: string;
	// 组件change 事件名称，如select组件为：'select'
	changeEvent?: string;
	valueField?: string;
	// 默认值
	defaultValue?: any;
	// 为每个form.item 设置样式
	style?: Recordable;
	label: string | Fn | VNode;
	// 每个formitem的label宽度
	labelWidth?: string | number;
	// 使全局的在formconfig里定义的labelwidth 失效，使用内部定义的
	invalidGlobalLabelWidth?: boolean;
	subLabel?: string;

	// form-item里面的组件
	component: ComponentType;
	// antd组件对应的具体的属性
	componentProps?:
		| object
		| ((opt: {
				schema: FormSchema;
				tableAction: TableActionType;
				formActionType: FormActionType;
				formModel: Recordable;
		  }) => Recordable);
	renderComponentContent?: ((renderCallbackParams: RenderCallbackParams) => any) | VNode | VNode[] | string;

	// label 右侧的提示文字
	helpMessage?: string | string[];
	// BasicHelp 组件的props
	helpComponentProps?: Partial<HelpComponentProps>;

	required?: boolean;

	suffix?: string | number | ((values: RenderCallbackParams) => string | number);

	rules?: Rule[];
	// 是否将label加入到错误信息中（当不提供错误信息时自动生成）
	rulesMessageJoinLabel?: boolean;

	// 自定义插槽
	slot?: string;
	// Custom slot, similar to renderColContent
	colSlot?: string;

	// 是否显示(display:none)
	show?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
	// 是否显示（当显示展开按钮时起作用）
	ifShow?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
	// 是否将该 form.item 放入展开按钮中
	isAdvanced?: boolean;

	// Render the content in the form-item tag
	render?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;

	// form.item props(antd)
	itemProps?: Partial<FormItemProps>;
	// row-col布局，使用col后，将替换掉form.item的margin-right样式
	colProps?: Partial<ColEx>;
	renderColContent?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;
	// 单独控制冒号
	colon?: boolean;
	// 动态控制Form.Item disable
	dynamicDisabled?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
	dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[];
}

export interface HelpComponentProps {
	maxWidth: string;
	// Whether to display the serial number
	showIndex: boolean;
	// Text list
	text: any;
	// colour
	color: string;
	// font size
	fontSize: string;
	icon: string;
	absolute: boolean;
	// Positioning
	position: any;
}

export interface FormActionType {
	submit: () => Promise<void>;
	setFieldsValue: <T extends Recordable>(values: T) => Promise<void>;
	resetFields: (nameList?: NamePath[]) => Promise<void>;
	// 删除多个指定的字段值
	resetField: (nameList: NamePath[]) => Promise<void>;
	// 获取一个:'string'或多个string[]值
	getFieldValue: <T>(values: NamePath) => T;
	// 获取所有字段的值
	getFieldsValue: () => Recordable;
	clearValidate: (name?: string | string[]) => Promise<void>;
	updateSchema: (data: Partial<FormSchema> | Partial<FormSchema>[]) => Promise<void>;
	resetSchema: (data: Partial<FormSchema> | Partial<FormSchema>[]) => Promise<void>;
	setProps: (formProps: Partial<FormProps>) => Promise<void>;
	removeSchemaByFiled: (field: string | string[]) => Promise<void>;
	appendSchemaByField: (
		schema: FormSchema,
		prefixField: string | undefined,
		first?: boolean | undefined,
	) => Promise<void>;
	validateFields: (nameList?: NamePath[]) => Promise<any>;
	validate: (nameList?: NamePath[]) => Promise<any>;
	scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>;
}
